//
//  main.c
//  Questions
//
//  Created by wangrui.
//  Copyright (c) 2014年 wangrui. All rights reserved.
//

/*
 *图(无向)的最小生成树 prim算法
 *
 *2014-10-08 15:46:02
 *测试数据:
	6 9
	2 4 11
	3 5 13
	4 6 3
	5 6 4
	2 3 6
	4 5 7
	1 2 1
	3 4 9
	1 3 2
 */

#include <stdio.h>
#include <stdlib.h>
#include "cutils.h"

#ifdef DEBUG
#undef DEBUG
#define DEBUG 0
#endif

#define INF 999999

int main(int argc, const char * argv[])
{
	
	int n,m;
	scanf("%d %d",&n,&m);
	
	int e[n+1][n+1],dis[n+1],flag[n+1];//邻接矩阵、距离和标志数组
	
	//初始化
	for (int i=0; i<=n; i++) {
		for (int j=0; j<=n; j++) {
			if (i==j) {
				e[i][j] = 0;
			}
			else{
				e[i][j] = INF;
			}
		}
	}
	
	for (int i=0; i<=n; i++) {
		dis[i] = 0;
		flag[i] = 0;
	}
	
	//读入边
	int t1,t2,t3;
	for(int i=1; i<=m;i++) {
		scanf("%d %d %d",&t1,&t2,&t3);
		
		//因为是无向图,值要存入两个
		e[t1][t2] = t3;
		e[t2][t1] = t3;
	}
	
	//第一点到各点的距离存入dis数组，当做默认距离
	for (int i=1; i<=n; i++) {
		dis[i] = e[1][i];
	}
	
	int count=0,sum=0;
	
	flag[1]=1;//标记一号顶点已经加入生成树
	count++;
	
	while (count < n) {
		
		int minIdx = 0;
		
		//找到最小值
		int min = INF;
		for (int i=1; i<=n; i++) {
			if (flag[i]==0 && dis[i]<min) {
				min = dis[i];
				minIdx = i;
			}
		}
		
		//将该点确认，加入最小生成树
		flag[minIdx]=1;
		count++;
		
		//加和记录该点的权重
		sum += dis[minIdx];
		
		//更新距离
		for(int k=0; k<=n; k++) {
			if (flag[k]==0 && dis[k] > e[minIdx][k]) {
				dis[k] = e[minIdx][k];
			}
		}
	}
	
	printf("the min weight:%d\n", sum);
	
	return 0;
}


